import Vue from 'vue'
import VueRouter from 'vue-router'
// 一级路由
import layout from '@/views/layout.vue'
import detail from '@/views/detail.vue'
import login from '@/views/login.vue'
import register from '@/views/register.vue'

// 二级路由
import article from '@/views/article.vue'
import collect from '@/views/collect.vue'
import like from '@/views/like.vue'
import user from '@/views/user.vue'

// 导入路由守卫
import { getToken } from '@/utils/storage.js'
// 导入vant轻提示
import { Toast } from 'vant'

Vue.use(VueRouter)

const routes = [
  /*
  一级路由： 凡是单个页面，独立展示的，都是一级路由
  二级路由特征：有tan栏切换的
   */
  {
    path: '/layout',
    component: layout,
    children: [
      { path: '/', redirect: '/article' },
      { path: '/article', component: article },
      { path: '/collect', component: collect },
      { path: '/like', component: like },
      { path: '/user', component: user }
    ]
  },
  { path: '/detail', component: detail },
  // 准备动态路由 点击首页的详情 传参(id) 并跳转
  // { path: '/detail/:id', component: detail }, // 这个是params方法 老师用的query方法 不用动态路由传参了
  { path: '/login', component: login },
  { path: '/register', component: register },
  // 重定向
  { path: '/', redirect: '/layout' },
  { path: '*', redirect: '/layout' }
]

// 实例化路由对象
const router = new VueRouter({
  routes
})

// 全局前置守卫：
// 1. 所有的路由一旦被匹配到，在真正渲染解析之前，都会先经过全局前置守卫
// 2. 只有全局前置守卫放行，才能看到真正的页面

// 任何路由，被解析访问前，都会先执行这个回调
// 1. from 你从哪里来， 从哪来的路由信息对象
// 2. to   你往哪里去， 到哪去的路由信息对象
// 3. next() 是否放行，如果next()调用，就是放行 => 放你去想去的页面
//    next(路径) 拦截到某个路径页面

const whiteList = ['/login', '/register'] // 白名单列表，记录无需权限访问的所有页面

// 给路由对象 添加: 全局前置守卫
router.beforeEach((to, from, next) => {
  /*
  to : 要到哪里去 (要跳转到哪里去)
  from:从哪里来   (从哪个页面跳转)
  next:
    next() : 正常放行.跳转到to的页面
    next('/路径') : 拦截. 调转到指定的页面
  */
  //  业务: 登录权限 . (没有登录, 就不能访问首页)
  //  什么时候可以跳转登录页 : 有token  || 白名单页面

  // 如果有token，直接放行
  // 没有token的人, 看看你要去哪
  // (1) 访问的是无需授权的页面（白名单），也是放行
  //     就是判断，访问的地址，是否在白名单数组中存在 includes
  if (getToken() || whiteList.includes(to.path)) {
    next()
    // (2) 否则拦截到登录
  } else { // 没有token , 也不是白名单页面。 就拦住你让你去登录页
    Toast.fail('请先登录')
    next('/login')
  }
})

/*
这个 面经移动端 项目，只对 登录用户 开放，如果未登录，一律拦截到登录
1. 如果访问的是 **首页**，     无token， 拦走
2. 如果访问的是 **列表页**，无token， 拦走
3. 如果访问的是 **详情页**，无token， 拦走
   ....
分析：哪些页面，是不需要登录，就可以访问的！  =>  **注册**   和   **登录**  （白名单 - 游客可以随意访问的）
核心逻辑：
1. 判断用户有没有token， 有token， 直接放行  （有身份的人，想去哪就去哪~）
2. 没有token（游客），如果是白名单中的页面，直接放行
3. 否则，无token（游客），且在访问需要权限访问的页面，直接拦截到登录
*/
/*
刚开始接触路由导航守卫你会发现和axios拦截器有点像，实际上它们是两个不同的东西。
1.相同点
       (1)都是钩子函数(回调函数的一种,到某个时机了自动触发)
       (2)都是起到拦截作用
2.不同点
       (1)功能不同 :  axios拦截器`拦截网络请求`,  导航守卫`拦截路由跳转`
       (2)应用场景不同 :
                 axios拦截器一般用于发送token
               导航守卫用于`页面跳转权限管理`(有的页面可以无条件跳转,例如登录注册页可以无条件跳转。有的页面需要满足条件才能跳转，例如购物车页面就需要用户登录才可以跳转)
*/
/*
- 官网文档：[路由导航守卫]
- 1.什么是路由导航守卫？ ： 通俗来讲，就是`路由跳转`的时候需要`执行`的一个`回调函数`
  - 路由导航：就是路由跳转的意思
  - 守卫：类似于`门卫`，你做某件事之前会对你进行一个检查
- 2.为什么要有路由导航守卫
  - 在项目开发中，并不是每一个路由跳转都是`明确`的。 例如很多页面跳转需要登录判断，如果你有登录，则跳转到指定页面，没有登录则跳转到登录页面。
    - 举例子：我想进小区(个人信息)，门卫（导航守卫）会检查我有没有做核酸(是否登录)，如果做了就让我进去（跳转个人信息）。没做就让我去核酸点（登录页面）做完核算才可以进去。
- 3.路由导航守卫有哪些？
  - 前置守卫：跳转前执行
  - 后置勾子：跳转后执行
  - 导航守卫语法介绍(`导航守卫需要创建完路由对象之后才能使用`)：
  - ==一定要注意，在导航守卫中必须要调用`next()`否则你的路由无法跳转==
*/
export default router
